package com.huage.courseplatform.application.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.huage.courseplatform.application.mapper.*;
import com.huage.courseplatform.application.model.entity.*;
import com.huage.courseplatform.application.service.SignService;
import com.huage.courseplatform.framework.utils.date.DateUtils;
import com.huage.courseplatform.framework.utils.date.LocalDateTimeUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SignServiceImpl implements SignService {
    @Resource
    TeacherSignMapper teacherSignMapper;

    @Resource
    PeriodMapper periodMapper;

    @Resource
    StudentLeaveMapper studentLeaveMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void teacherSign(String teacherId, String periodId) {
        //删除存在的记录
        teacherSignMapper.delete(new QueryWrapper<PeriodTeacherSign>().eq("period_id",periodId));
        teacherSignMapper.delStudentSignByPeriod(periodId);

        ///获取当前时间
        String signTimeString = DateUtils.getTime();
        //校验课时时间
        checkSignTime(periodId,signTimeString);

        //添加教师学生签到记录
        PeriodTeacherSign sign  = new PeriodTeacherSign();
        sign.setTeacherId(teacherId);
        sign.setPeriodId(periodId);
        sign.setSignTime(signTimeString);

        Period period = periodMapper.selectById(periodId);
        Assert.isTrue(!ObjectUtils.isEmpty(period),"找不到对应课时");

        List<Student> studentList = periodMapper.getStudentListById(periodId);
        List<String> studentIdList = studentList.stream().map(Student::getId).collect(Collectors.toList());

        List<String> studentSignList = studentIdList;

        //列表去掉请假
        List<PeriodStudentLeave> studentLeaveList = studentLeaveMapper.selectList(new QueryWrapper<PeriodStudentLeave>().eq("period_id",periodId));
        if(!CollectionUtils.isEmpty(studentLeaveList)){
            List<String> studentIdLeaveList = studentLeaveList.stream().map(PeriodStudentLeave::getStudentId).collect(Collectors.toList());
            studentSignList = studentIdList.stream().filter(s -> !studentIdLeaveList.contains(s)).collect(Collectors.toList());
        }

        //插入学生签到数据
        studentSignList.forEach(studentId -> {
            teacherSignMapper.addStudentSign(studentId,periodId);
        });

        teacherSignMapper.insert(sign);

    }


    @Override
    public Boolean teacherHavePeriod(String periodId, String teacherId) {
        Period period = periodMapper.selectById(periodId);
        if (ObjectUtils.isEmpty(period)){
            return false;
        }
        if(period.getTeacherId().equals(teacherId)){
            return true;
        }
        return false;
    }

    @Override
    public void studentLeave(PeriodStudentLeave periodStudentLeave) {
        studentLeaveMapper.insert(periodStudentLeave);
    }

    @Override
    public List<Student> getStudentLeave(String periodId) {
        return studentLeaveMapper.getStudentListByPeriodId(periodId);
    }

    @Override
    public List<Student> getStudentSign(String periodId) {
        List<Student> studentLeaveList = studentLeaveMapper.getStudentListByPeriodId(periodId);

        Period period = periodMapper.selectById(periodId);
        Assert.isTrue(ObjectUtils.isEmpty(period),"查询不到相关课程信息");
        List<Student> studentList = periodMapper.getStudentListById(periodId);
        //去除请假人员
        List<Student> studentSignList = studentList.stream().filter(student -> !studentLeaveList.contains(student)).collect(Collectors.toList());
        return studentSignList;
    }

    /**
     * 校验签到时间是否在课程时间内
     * @param periodId
     * @param signTimeString
     */
    private void checkSignTime(String periodId,String signTimeString){
        Period period = periodMapper.selectById(periodId);

        String startTimeString = period.getStartTime();
        String endTimeString = period.getEndTime();

        LocalDateTime signTime = LocalDateTimeUtil.parse(signTimeString);

        //开始前10分钟时间 ~ 结束后10分钟
        LocalDateTime startTime = LocalDateTimeUtil.parse(startTimeString).minusMinutes(10);
        LocalDateTime endTime = LocalDateTimeUtil.parse(endTimeString).plusMinutes(10);;

        Assert.isTrue(!LocalDateTimeUtil.isBefore(signTime,startTime),"未到签到时间,请在签到时间内签到");
        Assert.isTrue(!LocalDateTimeUtil.isAfter(signTime,endTime),"签到时间已过,需要请补签");

    }
}
